#include "scripter.h"
#include "WijiUi.h"
#include "wijiuiscriptable.h"
#include <QDebug>
#include <QFile>
#include <QTextStream>
#include <iostream>
#include <fstream>
#include <QMessageBox>

Scripter::Scripter(QObject* parent)
: engine(parent) {

}
void Scripter::init() {
    browserHtml = "";
}
void Scripter::add(QString name, QObject *object) {
    QScriptValue item = engine.newQObject(object);
    QScriptValue global = engine.globalObject();
    global.setProperty(name,item);
}
void Scripter::exec(QString filename) {
    QFile file(filename);
    file.open(QIODevice::ReadOnly);
    QString contents = QTextStream(&file).readAll();
    file.close();
    engine.evaluate(contents);
}
QScriptValue& Scripter::runQtScript(QString filename) {
    QFile scriptFile(filename);
     scriptFile.open(QIODevice::ReadOnly);
     QString contents = scriptFile.readAll();
     if (!engine.canEvaluate(contents)) {
         QMessageBox::critical(0, QObject::tr("Critical Script Error"), QObject::tr("Wiji Cannot evaluate this script `") + filename + QObject::tr("`, are you sure it is QSA?"));
     } else {
         QScriptValue wiji = engine.newQObject(WijiUiScriptable::getSelf(),QScriptEngine::ScriptOwnership);
         QScriptValue global = engine.globalObject();
         if (!global.property(QLatin1String("wiji")).isValid()) {
             global.setProperty(QLatin1String("wiji"), wiji);
         }
         if (!global.property(QLatin1String("_wiji_reserved_output")).isValid()) {
             global.setProperty(QLatin1String("_wiji_reserved_output"), "");
         }
         engine.evaluate("_wiji_reserved_output = ''; print = function (str) { _wiji_reserved_output = _wiji_reserved_output + str;}");
         engine.evaluate(contents);
         // Why this? Because it's too much of a dance to get QtScripts print function to return a value, this way, we skip it all together
         // and just define print = function etc.. then call the output variable. This has added secret benefits, like being able to modify the output
         // from within the program even if it's already been printed.
         result = engine.evaluate("_wiji_reserved_output");
         scriptFile.close();
         if (engine.hasUncaughtException()) {
             QScriptValue exception = engine.uncaughtException();
             QMessageBox::critical(0,QObject::tr("Script Error"),QString(QObject::tr("Engine threw an uncaught exception. ")) + exception.toString());
         }
    }
    return result;
}
bool Scripter::hasErrors() {
    if (engine.hasUncaughtException()) {
        //We should return some errors here.
        //sendResult(result, header);
        qDebug() << engine.uncaughtException().toString();
        qDebug() << engine.uncaughtExceptionBacktrace().join("\n");

        return true;
    }
    return false;
}
QScriptValue& Scripter::evalCode(QString code) {
    return result = engine.evaluate(code);
}
